package com.starblink.imgsearch.result.ui

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.apollographql.apollo3.api.ApolloResponse
import com.apollographql.apollo3.api.Optional
import com.starblink.android.basic.base.BaseViewModel
import com.starblink.android.basic.data.model.product.ProductFWrap
import com.starblink.android.basic.data.model.product.RecommendProductF
import com.starblink.android.basic.ext.toast
import com.starblink.android.basic.extension.apollo.toWrap
import com.starblink.android.basic.network.base.SkGqlClient
import com.starblink.basic.apollo.ext.optional
import com.starblink.android.basic.sensorsdata.room.entity.SkAntEntity
import com.starblink.android.basic.sensorsdata.spm.GTrackerAssistUtils
import com.starblink.android.basic.sensorsdata.spm.cfg.SpmElementDef
import com.starblink.android.basic.sensorsdata.spm.cfg.SpmPageDef
import com.starblink.android.basic.sensorsdata.spm.impl.SpmTrackHandler
import com.starblink.android.basic.user.UserDataCenter
import com.starblink.android.basic.util.bus.FlowBus
import com.starblink.android.basic.util.bus.FlowConst
import com.starblink.imgsearch.result.data.ForYouTitleModel
import com.starblink.imgsearch.result.data.ResultBrandModel
import com.starblink.imgsearch.result.data.ResultPriceModel
import com.starblink.imgsearch.result.data.ResultTipModel
import com.starblink.imgsearch.result.data.SeeMoreItemModel
import com.starblink.rocketreserver.GuessYouLikeProductByPicSearchQuery
import com.starblink.rocketreserver.ImageIdentify4picV2Query
import com.starblink.rocketreserver.ImageIdentify4postPicQuery
import com.starblink.rocketreserver.RecommendProductWhenSearchByPicNoResultQuery
import com.starblink.rocketreserver.fragment.PicSearchResultF
import com.starblink.rocketreserver.fragment.ProductF
import com.starblink.rocketreserver.fragment.SearchWordVOF
import com.starblink.rocketreserver.type.PicSearchQuery
import com.starblink.rocketreserver.type.RecommendProductWhenSearchByPicNoResultParam
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * 图搜结果子页VM
 */
internal class TabViewModel : BaseViewModel() {


    //    val seeMoreItem = SeeMoreItemModel("seemore")
    val forUItem = ForYouTitleModel("for you")
//    val tipItem = ResultTipModel(0.0)

    val adapterList = arrayListOf<Any>()

    /**
     * 结果list集合
     */
    val products = arrayListOf<ProductFWrap>()

    /**
     * 推荐list集合
     */
    val recProducts = arrayListOf<RecommendProductF>()

    val resultLD = MutableLiveData<List<ProductFWrap>>()

    val recommendLD = MutableLiveData<List<RecommendProductF>>()

    val loadStateLD = MutableLiveData<Int>()

    var pageNo = 1

    var recommendPageNo = 0

    var mTopTotalNum: Int = 0

    var picUrl = ""

    var regin = ""

    var postPicAiId: String? = null

    var saleableCountryFlag = DEFAULT_COUNTRY_FLAG

    var selectOtherCountryFlag: Boolean? = null

    var currentCountryIsolateFlag: Boolean? = null

    private var initRequestJob: Job? = null

    //顶部品牌
    var brandMapList: HashMap<Int, ArrayList<ResultBrandModel>>? = null
    var priceMapList: HashMap<Int, ResultPriceModel>? = null
    var searchWordMapList: HashMap<Int, List<PicSearchResultF.SearchWordList?>?>? = null
    var tabPosition = 0
    var hasSetBrand = false //true-已加载相关品牌,false-未加载，默认false

    fun forUItemIndex() = adapterList.indexOfFirst { it == forUItem }

//    fun seeMoreItemIndex() = adapterList.indexOfFirst { it == seeMoreItem }

    fun initAdapterList() {
        adapterList.run {
            if (products.isNotEmpty()) {
//                add(0, tipItem.apply {
//                    firstScore = products.firstOrNull()?.productF?.score ?: 0.0
//                    visible = products.isNotEmpty()
//                })
                addAll(products)
//                add(seeMoreItem.apply {
//                    enable = true
//                    visible = products.isNotEmpty()
//                })
            }
            if (recProducts.isNotEmpty()) {
                add(forUItem.apply {
                    visible = recProducts.isNotEmpty()
                })
                addAll(recProducts)
            }
        }
    }


    /**
     * 初始化数据优先请求结果，再请求推荐
     */
    fun loadInitData() {
        initRequestJob = viewModelScope.async {
            loadData()?.let { it ->
                products.addAll(it)
                resultLD.postValue(it)
            }
            loadRecData()?.let { it ->
                recProducts.addAll(it)
                recommendLD.postValue(it)
            }
        }
    }

    private suspend fun loadData(): List<ProductFWrap>? =
        if (postPicAiId?.isNotEmpty() == true) {
            // 图搜和内容相关
            SkGqlClient.skQuery(
                query = ImageIdentify4postPicQuery(
                    params = PicSearchQuery(
                        postPicAiInfoId = postPicAiId.optional(),
                        pageNo = pageNo.optional(),
                        pageSize = pageSize.optional(),
                        regin = regin.optional(),
                        saleableCountryFlag = saleableCountryFlag.optional(),
                    )
                )
            )?.data?.imageIdentify4postPic?.picSearchResultF?.apply {
                this@TabViewModel.selectOtherCountryFlag = this.selectOtherCountryFlag
                this@TabViewModel.currentCountryIsolateFlag = this.currentCountryIsolateFlag
                priceMapList?.get(tabPosition)?.currentCountryIsolateFlag =
                    this.currentCountryIsolateFlag
            }.apply {
                searchWordMapList!![tabPosition] = this?.searchWordList
                mTopTotalNum = this?.total ?: 0
                FlowBus.with<Int>(FlowConst.IMG_SEARCH_OOPS).post(tabPosition)
                FlowBus.with<Int>(FlowConst.IMG_SEARCH_KEY_WORD).post(tabPosition)
            }?.list?.mapIndexedNotNull { i, it -> it?.productF?.toWrap(products.size + i) }
        } else {
            // 商品图搜
            var brandQuery: ArrayList<String>? = null
            brandMapList?.let {
                try {
                    for ((i, item) in it[tabPosition]!!.withIndex()) {
                        if (i != 0 && item.selected) {
                            if (brandQuery == null) {
                                brandQuery = arrayListOf()
                            }
                            brandQuery!!.add(item.brandTxt)
                        }
                    }
                } catch (e: Exception) {
                }
            }
            // todo 加参数
            SkGqlClient.skQuery(
                query = ImageIdentify4picV2Query(
                    search = PicSearchQuery(
                        picUrl = picUrl.optional(),
                        pageNo = pageNo.optional(),
                        pageSize = pageSize.optional(),
                        regin = regin.optional(),
                        saleableCountryFlag = saleableCountryFlag.optional(),
                        brands = brandQuery.optional(),
                        sortType = (priceMapList?.get(tabPosition)?.status ?: 0).optional()
                    ),
                )
            )?.data?.imageIdentify4picV2?.picSearchResultF?.apply {
                this@TabViewModel.selectOtherCountryFlag = this.selectOtherCountryFlag
                this@TabViewModel.currentCountryIsolateFlag = this.currentCountryIsolateFlag
                priceMapList?.get(tabPosition)?.currentCountryIsolateFlag =
                    this.currentCountryIsolateFlag
            }.apply {
                searchWordMapList!![tabPosition] = this?.searchWordList
                mTopTotalNum = this?.total ?: 0
                if (tabPosition != 0 && brandMapList != null && !hasSetBrand) {
                    var list = arrayListOf<ResultBrandModel>()
                    // todo 加Sale
                    list.add(ResultBrandModel(true, "All", "-1"))
                    //默认All时给一个点击
                    SpmTrackHandler.addSingleTrackData(
                        SkAntEntity(
                            spmCnt = GTrackerAssistUtils.fetchElementValue(
                                SpmPageDef.GdsAndPostItemTab,
                                SpmElementDef.Element_33049
                            ),
                        )
                    )
                    this?.filterBrandList?.let {
                        for ((i, item) in it.withIndex()) {
                            if (i < 5) {//取前5
                                item?.brandVOF?.name?.let { name ->
                                    list.add(
                                        ResultBrandModel(
                                            false,
                                            name,
                                            item.brandVOF?.id ?: ""
                                        )
                                    )
                                }
                            }
                        }
                    }
                    brandMapList!![tabPosition] = list
                    hasSetBrand = true
                }
                FlowBus.with<Int>(FlowConst.IMG_SEARCH_SWITCH_PAGE).post(tabPosition)
                FlowBus.with<Int>(FlowConst.IMG_SEARCH_KEY_WORD).post(tabPosition)
            }?.list?.mapIndexedNotNull { i, it -> it?.productF?.toWrap(products.size + i) }
        }

    fun loadMoreRecData() {
        recommendPageNo++
        viewModelScope.launch {
            val response = loadRecData()
            response?.let { it ->
                recProducts.addAll(it)
                recommendLD.postValue(it)
            }
            loadStateLD.postValue(LOAD_STATE_FINISH)

        }
    }

    private suspend fun loadRecData(): List<RecommendProductF>? =

        if (products.isNotEmpty()) {
            recommendPageNo++
            SkGqlClient.skQuery(
                query = GuessYouLikeProductByPicSearchQuery(
                    picSearchQuery = PicSearchQuery(
//                        postPicAiInfoId = postPicAiId.optional(),
                        picUrl = if (picUrl.isNotEmpty()) picUrl.optional() else Optional.Absent,
                        pageNo = recommendPageNo.optional(),
                        pageSize = pageSize.optional(),
                        regin = regin.optional(),
                        saleableCountryFlag = saleableCountryFlag.optional(),
                        sortType = 0.optional(),
                        needGuidance = false.optional(),
                    )
                )
            )?.data?.guessYouLikeProductByPicSearch.apply {
                if (this.isNullOrEmpty()) {
//                    toast("tab $tabPosition  没数据1")
                }
            }?.mapNotNull { it?.productF }
        } else {
            recommendPageNo++
            SkGqlClient.skQuery(
                query = RecommendProductWhenSearchByPicNoResultQuery(
                    params = RecommendProductWhenSearchByPicNoResultParam(
                        pageNo = recommendPageNo,
                        pageSize = pageSize,
                        photoUrl = if (picUrl.isNotEmpty()) picUrl.optional() else Optional.Absent,
                    )
                )
            )?.data?.recommendProductWhenSearchByPicNoResult.apply {
                if (this.isNullOrEmpty()) {
//                    toast("tab $tabPosition 没数据2")
                }
            }?.map { it.productF }
        }?.mapIndexed { index, it -> RecommendProductF(it, index + recProducts.size) }


    fun resetData() {
        pageNo = 1
        recommendPageNo = 0

        adapterList.clear()
        products.clear()
        recProducts.clear()
        initRequestJob?.cancel()
    }


//    private fun canLoadRecommendData(): Boolean {
////        return if (recommendPageNo > 0) {
////            true
////        } else {
////            pageSize * pageNo >= mTopTotalNum
////        }
//    }


    companion object {
        const val pageSize = 10
        const val LOAD_STATE_FINISH = 100
        const val DEFAULT_COUNTRY_FLAG = true
    }


}